package com.yhk.wuchat.common.user.service.impl;

import cn.hutool.core.util.StrUtil;
import com.yhk.wuchat.common.common.constant.RedisKey;
import com.yhk.wuchat.common.common.util.JwtUtils;
import com.yhk.wuchat.common.common.util.RedisUtils;
import com.yhk.wuchat.common.user.service.LoginService;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Objects;
import java.util.concurrent.TimeUnit;

/**
 * @version 1.0
 * @Author moresuo
 * @Date 2024/4/6 15:25
 * @注释
 */
@Service
public class LoginServiceImpl implements LoginService {

    public static final int TOKEN_EXPIRE_DAYS = 3;
    public static final int TOKEN_RENEWAL_DAYS = 1;
    @Resource
    private JwtUtils jwtUtils;

    /**
     * 异步刷新token
     * @param token
     */
    @Override
    @Async//异步处理
    public void renewalTokenIfNecessary(String token) {
        //获取uid
        Long uid = getValidUid(token);
        //根据uid获取Redis中的token
        String userTokenKey = getUserTokenKey(uid);
        //获取过期时间
        Long Days = RedisUtils.getExpire(userTokenKey, TimeUnit.DAYS);
        if(Days==-2){//不存在的key
            return;
        }
        if(Days< TOKEN_RENEWAL_DAYS){
            RedisUtils.expire(userTokenKey,TOKEN_EXPIRE_DAYS,TimeUnit.DAYS);
        }
    }

    /**
     * 用户登录生成Token
     * @param uid
     * @return
     */
    @Override
    public String login(Long uid) {

        String token = jwtUtils.createToken(uid);
        RedisUtils.set(getUserTokenKey(uid),token,TOKEN_EXPIRE_DAYS, TimeUnit.DAYS);
        return token;
    }

    /**
     * 获取有效的uid
     * @param token
     * @return
     */
    @Override
    public Long getValidUid(String token) {
        Long uid = jwtUtils.getUidOrNull(token);
        if (uid == null) {
            return null;
        }
        String oldToken = RedisUtils.getStr(getUserTokenKey(uid));
        if (StrUtil.isBlank(oldToken)) {
            return null;
        }
        return Objects.equals(oldToken,token)?uid:null;
    }

    /**
     *
     * @param uid
     * @return
     */
    private String getUserTokenKey(Long uid) {
        return RedisKey.getKey(RedisKey.USER_TOKEN_STRING, uid);
    }
}
